﻿using CustomCharacter;
using CustomPlayerEffects;
using Exiled.API.Features;
using InventorySystem.Items.Firearms;
using InventorySystem.Items;
using InventorySystem;
using MEC;
using PlayerRoles;
using PlayerStatsSystem;
using RgCore.Events;
using RgCore.API;
using RgCore.Misc;
using RgCore.PlayerHud;
using System;
using System.Collections.Generic;
using UnityEngine;
using InventorySystem.Items.Firearms.Attachments;
using System.Linq;
using Exiled.Events.EventArgs.Interfaces;
using Exiled.Events.EventArgs.Player;
using VoiceChat;
using Exiled.API.Enums;
using CustomCharacter.Ability;
using CustomCharacter.Interfaces;
using RgCore.CustomSide;

namespace Scp378
{
    [RoleInfo("SCP-378", Side.Scp, PlayerRoles.RoleTypeId.ClassD, PlayerRoles.RoleTypeId.ClassD)]
    public class Scp378 : CustomCharacter.CustomCharacter, IRoundStartSpawn, IScpNumber, ITrialCard, IVoiceChannelModifcation
    {
        public Scp378(int id) : base(id)
        {
        }

        public int Cost => 350;
        public override Color32 RoleColor => new Color32(63, 73, 185, 255);
        public byte MinPlayers => 13;
        public string ScpNumber => "378";
        public VoiceChatChannel[] AvailableVoiceChannels => new VoiceChatChannel[] { VoiceChatChannel.ScpChat };

        public bool PrimaryModification => true;

        public bool Ability1_Check(Player player, out string response)
        {
            var ab = player.GetAbility("Scp378_Attr_1");
            if (ab.Ability == null)
            {
                response = "此技能需要SCP-378的特性技能才能正常使用";
                return false;
            }
            var data = ab.Datas;
            var occuping = (bool)data["occuping"];
            var HasParasitifer = (bool)data["has_parasitifer"];
            if (HasParasitifer)
            {
                response = "当前有宿主了";
                return false;
            }
            if (occuping)
            {
                response = "寄生中";
                return false;
            }
            response = "";
            return true;
        }

        public static AbilityOutput Ability1(Player player, ref AbilityInfo info, IExiledEvent e, AbilityTrigger trigger)
        {
            var ab = player.GetAbility("Scp378_Attr_1");
            if (ab.Ability == null)
                return new AbilityOutput(false, "此技能需要SCP-378的特性技能才能正常使用");
            var data = ab.Datas;
            var occuping = (bool)data["occuping"];
            var HasParasitifer = (bool)data["has_parasitifer"];
            var tar = player.IsPointingAt(3f);
            if (tar == null)
            {
                if (!player.HasMsg("target_not_found"))
                {
                    player.SendFormattedMsg("target_not_found", $"<color=#FFAAAA>失败</color>", "未找到目标", 2, MsgType.Failed_Response, ScreenLocation.CenterTop, true);
                }
                return new AbilityOutput(false);
            }
            if (player.IsFriendly(tar))
            {
                return new AbilityOutput(false, "该玩家为你的队友");
            }
            if (tar.Role.Type == PlayerRoles.RoleTypeId.Tutorial)
            {
                return new AbilityOutput(false, "该角色禁止被寄生");
            }
            data["occuping"] = true;
            tar.EnableEffect<Ensnared>(1, 2);
            player.EnableEffect<Ensnared>(1, 2);
            RoleTypeId tar_role = tar.Role;
            List<ItemType> items = (from x in tar.Inventory.UserInventory.Items.Values.ToList() select x.ItemTypeId).ToList();
            var ammo = new Dictionary<ItemType, ushort>(tar.Inventory.UserInventory.ReserveAmmo);
            Timing.CallDelayed(2.0f, delegate ()
            {
                try
                {
                    if (player.IsAlive)
                    {
                        player.Role.Set(tar_role, RoleSpawnFlags.None);
                        foreach (var key in items)
                        {
                            ItemBase ib = player.Inventory.ServerAddItem(key);
                            if (ib is Firearm firearm)
                            {
                                Firearm origin = ib as Firearm;
                                firearm.ApplyAttachmentsCode(origin.GetCurrentAttachmentsCode(), true);
                                firearm.Status = new FirearmStatus(firearm.AmmoManagerModule.MaxAmmo, origin.Status.Flags, firearm.GetCurrentAttachmentsCode());
                            }
                        }
                        player.Inventory.UserInventory.ReserveAmmo = ammo;
                        player.Inventory.SendAmmoNextFrame = true;
                        data["has_parasitifer"] = true;
                        player.Scale = Vector3.one;
                        player.AddScore(100, "寄生");
                        tar.ClearInventory(true);
                        tar.Kill(new CustomReasonDamageHandler("被SCP-378寄生"));
                    }
                    data["occuping"] = false;
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                }
            });
            return new AbilityOutput(true);
        }

        private static AbilityOutput Attribute_1(Player player, ref AbilityInfo info, IExiledEvent e, AbilityTrigger trigger)
        {
            var data = info.Datas;
            var occuping = (bool)data["occuping"];
            var HasParasitifer = (bool)data["has_parasitifer"];
            DateTime DieTime = DateTime.Parse(data["dietime"].ToString());
            if (trigger == AbilityTrigger.Update)
            {
                if (!HasParasitifer && !occuping && DieTime.AddSeconds(45) < DateTime.Now)
                {
                    player.Kill(new CustomReasonDamageHandler("失去养分"));
                }
                return new AbilityOutput(true);
            }
            if (trigger != AbilityTrigger.Event)
            {
                return new AbilityOutput(false);
            }
            if (e is HurtingEventArgs ev && ev.DamageHandler.Base is AttackerDamageHandler)
            {
                if (ev.Attacker == player && !HasParasitifer)
                {
                    ev.IsAllowed = false;
                    ev.Amount = 0f;
                }
                if (ev.Player == player && ev.Amount > 0 && ev.IsAllowed && !HasParasitifer)
                {
                    ev.Amount *= occuping ? 0.3f : 0.7f;
                    if (ev.Attacker.GetEffect(Exiled.API.Enums.EffectType.Ensnared)?.Duration > 0)
                    {
                        ev.Amount = 0f;
                        ev.IsAllowed = false;
                    }
                }
                return new AbilityOutput(true);
            }
            if (e is DyingEventArgs ev2 && ev2.Player == player && HasParasitifer)
            {
                if (ev2.DamageHandler.Base is WarheadDamageHandler || (ev2.DamageHandler.Base is UniversalDamageHandler && ev2.Player.TryGetEffect(EffectType.Decontaminating,out _)))
                {
                    return new AbilityOutput(true);
                }
                ev2.IsAllowed = false;
                ev2.Player.Role.Set(PlayerRoles.RoleTypeId.Scp0492, PlayerRoles.RoleSpawnFlags.None);
                Timing.CallDelayed(1.5f, () =>
                {
                    ev2.Player.MaxHealth = 30f;
                    ev2.Player.Health = ev2.Player.MaxHealth;
                });
                ev2.Player.DropItems();
                player.Scale = Vector3.one * 0.4f;
                data["dietime"] = DateTime.Now.ToString();
                data["has_parasitifer"] = false;
                return new AbilityOutput(true);
            }
            return new AbilityOutput(false);
        }

        public override IEnumerable<Ability> AbilityRegister()
        {
            return new Ability[]
            {
                new Ability("Scp378_1", "立刻寄生2.5米内所看向的敌对玩家，并继承玩家的身体", AbilityType.Offensive,
                0, Ability1, Ability1_Check, null, null, GetType()),
                new AttributeAbility("Scp378_Attr_1", "死亡脱离宿主，寄生伤害减免（具体请查看腾讯文档）",
                Attribute_1, true, new IExiledEvent[] { EventProcessor.OnDying, EventProcessor.OnHurting }
                , new KeyValuePair<string, object>[]
                {
                    new KeyValuePair<string, object>("has_parasitifer", true),
                    new KeyValuePair<string, object>("occuping", false),
                    new KeyValuePair<string, object>("dietime", DateTime.Now.ToString()),
                }, GetType())
            };
        }

        public override void Role_Deactive()
        {
            base.Role_Deactive();
            Timing.CallDelayed(1f, () =>
            {
                Player.Scale = Vector3.one * 1f;
            });
        }
    }
}